home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / CNews / Source / misc / canonhdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-30  |  4.7 KB  |  217 lines

  1. /*
  2.  * canonhdr - canonicalise RFC 1036 header
  3.  *    always capitalise header keywords
  4.  *    optionally canonicalise dates in Date: and Expires: headers
  5.  *    optionally convert 822 headers to 1036 headers
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <time.h>
  11. #include <sys/types.h>
  12. #include <sys/timeb.h>
  13. #include "news.h"
  14. #include "libc.h"
  15.  
  16. /* imports */
  17. extern int optind;
  18. extern char *optarg;
  19. extern FILE *efopen();
  20. extern char *strsave(), *str3save();
  21.  
  22. /* exports */
  23. char *progname;
  24. int debug;
  25.  
  26. /* privates */
  27. static int convdates = 0;
  28. static int convhdrs = 0;
  29.  
  30. /* forwards */
  31. char *mailtonews(), *canondate();
  32.  
  33. /*
  34.  * main - parse arguments and handle options
  35.  */
  36. main(argc, argv)
  37. int argc;
  38. char *argv[];
  39. {
  40.     int c, errflg = 0;
  41.  
  42.     progname = argv[0];
  43.     while ((c = getopt(argc, argv, "dm")) != EOF)
  44.         switch (c) {
  45.         case 'd':
  46.             ++convdates;
  47.             break;
  48.         case 'm':
  49.             ++convhdrs;
  50.             sethdrrfc(822);
  51.             break;
  52.         default:
  53.             errflg++;
  54.             break;
  55.         }
  56.     if (errflg) {
  57.         (void) fprintf(stderr, "usage: %s [-dm] [file]...\n", progname);
  58.         exit(2);
  59.     }
  60.  
  61.     if (optind >= argc)
  62.         process(stdin, "stdin");
  63.     else
  64.         for (; optind < argc; optind++)
  65.             if (STREQ(argv[optind], "-"))
  66.                 process(stdin, "-");
  67.             else {
  68.                 FILE *in = efopen(argv[optind], "r");
  69.  
  70.                 process(in, argv[optind]);
  71.                 (void) fclose(in);
  72.             }
  73.     exit(0);
  74. }
  75.  
  76. /*
  77.  * process - process input file
  78.  */
  79. process(in, inname)
  80. FILE *in;
  81. char *inname;
  82. {
  83.     register char *hdr, *nhdr;
  84.     int ishdr = YES;
  85.     long nolimit = -1;
  86.     static int washdr = YES;
  87.     static int dateseen = NO;
  88.     static char datenm[] =    "Date: ";
  89.     static char expiresnm[] = "Expires: ";
  90.  
  91.     if (!washdr)
  92.         return;
  93.     while ((hdr = gethdr(in, &nolimit, &ishdr)) != NULL && ishdr) {
  94.         register char *cp;
  95.         static char canonmsgid[] = "Message-Id:";
  96.         static char magicmsgid[] = "Message-ID:";
  97.  
  98.         /* capitalise first letter of each word, Message-ID: special */
  99.         for (cp = hdr; *cp != ':' && *cp != '\0'; cp++)
  100.             if (cp == hdr || cp[-1] == '-') {
  101.                 if (isascii(*cp) && islower(*cp))
  102.                     *cp = toupper(*cp);
  103.             } else
  104.                 if (isascii(*cp) && isupper(*cp))
  105.                     *cp = tolower(*cp);
  106.         if (STREQN(hdr, canonmsgid, STRLEN(canonmsgid)))
  107.             (void) strncpy(hdr, magicmsgid, STRLEN(magicmsgid));
  108.  
  109.         /* optionally convert 822 headers to 1036 headers */
  110.         if (convhdrs)
  111.             nhdr = mailtonews(hdr);
  112.         else
  113.             nhdr = hdr;
  114.  
  115.         /* optionally convert dates */
  116.         if (convdates && STREQN(nhdr, datenm, STRLEN(datenm))) {
  117.             dateseen = YES;
  118.             (void) fputs(datenm, stdout);
  119.             (void) fputs(canondate(nhdr, nhdr+STRLEN(datenm), 1),
  120.                 stdout);
  121.         } else if (convdates &&
  122.             STREQN(nhdr, expiresnm, STRLEN(expiresnm)) &&
  123.             nonnull(nhdr+STRLEN(expiresnm))) {
  124.             (void) fputs(expiresnm, stdout);
  125.             (void) fputs(canondate(nhdr, nhdr+STRLEN(expiresnm), 0),
  126.                 stdout);
  127.         } else
  128.             (void) fputs(nhdr, stdout);
  129.         /* must not free hdr; gethdr will do so automatically */
  130.         if (convhdrs)
  131.             free(nhdr);
  132.     }
  133.     if (hdr != NULL)
  134.         free(hdr);
  135.     if (!ishdr)
  136.         washdr = NO;
  137.     if (convdates && !dateseen) {
  138.         (void) fputs(datenm, stdout);
  139.         (void) fputs(canondate("now", "now", 0), stdout);
  140.     }
  141. }
  142.  
  143. int
  144. nonnull(s)
  145. char *s;
  146. {
  147.     register char *nwp = skipsp(s);
  148.  
  149.     return *nwp != '\n' && *nwp != '\0';
  150. }
  151.  
  152. char *                        /* malloced */
  153. mailtonews(hdr)
  154. char *hdr;
  155. {
  156.     register char *p;
  157.  
  158.     p = strchr(hdr, ':');
  159.     if (p == NULL)
  160.         return strsave(hdr);
  161.     p++;                    /* point just past colon */
  162.     if (*p == '\t')
  163.         *p = ' ';
  164.     if (*p == ' ')
  165.         return strsave(hdr);
  166.     else {
  167.         /* a spaceless colon; this means war! */
  168.         register char *nhdr = emalloc(strlen(hdr) + 1 + 1);
  169.         register int keyp1len = p - hdr;    /* keyword & colon */
  170.  
  171.         (void) memcpy(nhdr, hdr, keyp1len);    /* keyword & colon */
  172.         nhdr[keyp1len] = ' ';
  173.         (void) strcpy(nhdr + keyp1len + 1, hdr + keyp1len);
  174.         return nhdr;
  175.     }
  176. }
  177.  
  178. #define HIGH(nn) ((nn) / 10)
  179. #define LOW(nn)  ((nn) % 10)
  180.  
  181. char *
  182. canondate(hdr, vulgdate, abs)
  183. char *hdr, *vulgdate;
  184. int abs;                    /* flag: absolute date? */
  185. {
  186.     register struct tm *tm;
  187.     time_t date;
  188.     char *copydate;
  189.     static char chtime[128];
  190.     static char *days[] =
  191.         { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  192.     static char *months[] = {
  193.         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  194.         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  195.     };
  196.  
  197.     copydate = strsave(vulgdate);
  198.     if (abs)
  199.         date = getabsdate(copydate, (struct timeb *)NULL);
  200.     else                    /* TODO: use getreldate here */
  201.         date = getdate(copydate, (struct timeb *)NULL);
  202.     free(copydate);
  203.     if (date < 0) {
  204.         (void) fprintf(stderr, "%s: bad date in header: ", progname);
  205.         (void) fputs(hdr, stderr);
  206.         exit(1);
  207.     }
  208.     tm = gmtime(&date);
  209.     (void) sprintf(chtime, "%s, %d %s %d %d%d:%d%d:%d%d GMT\n",
  210.         days[tm->tm_wday],
  211.         tm->tm_mday, months[tm->tm_mon], tm->tm_year + 1900,
  212.         HIGH(tm->tm_hour), LOW(tm->tm_hour),
  213.         HIGH(tm->tm_min),  LOW(tm->tm_min),
  214.         HIGH(tm->tm_sec),  LOW(tm->tm_sec));
  215.     return chtime;
  216. }
  217.